package cn.calm.xhtml.api.service;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import cn.calm.xhtml.api.NodeProcess;
import cn.calm.xhtml.api.exception.XhtmlException;

public abstract class AbstraceNodeProcess implements NodeProcess {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static final String DEFAULT_ATTR_VALUE = "value";

	private String name;
	private String content;
	private NodeProcess[] children;
	private NodeProcess parent;
	private final Map<String, String> attr = new HashMap<String, String>();

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public NodeProcess[] getChildren() {
		return children;
	}

	public void setChildren(NodeProcess[] children) {
		this.children = children;
	}

	@Override
	public void setAttr(String name, String value) {
		attr.put(name, value);
	}

	@Override
	public String getAttr(String name) {
		return attr.get(name);
	}

	public Map<String, String> getAttr() {
		return Collections.unmodifiableMap(attr);
	}

	public NodeProcess getParent() {
		return parent;
	}

	public void setParent(NodeProcess parent) {
		this.parent = parent;
	}

	public Object getAttrValue(String string, XhtmlContext context) {
		String attr = getAttr(string);
		if (attr == null) {
			return null;
		}
		return getValue(attr, context);
	}

	public Object getValue(String express, XhtmlContext context) {
		if (express == null) {
			throw new XhtmlException("express is null");
		}
		Object expressValue;
		if (express.startsWith("${") && express.endsWith("}")) {
			expressValue = context.getValue(express);
		} else {
			expressValue = express;
		}
		return expressValue;
	}

	public void processChildren(XhtmlContext context) {
		NodeProcess[] children = getChildren();
		if (children == null) {
			return;
		}
		for (NodeProcess node : children) {
			node.processNode(context);
		}
	}

	public Object getValue(XhtmlContext context) {
		return getAttrValue(DEFAULT_ATTR_VALUE, context);
	}

	public void writeAttr(XhtmlContext context, String attr, String key, Object defaultValue) {
		ResponseWriter writer = context.getResponseWriter();
		Object value = getAttrValue(key, context);
		if (value == null && defaultValue != null) {
			value = defaultValue;
		}
		if (value != null) {
			writer.writeAttr(attr, value);
		}
	}

	public void writeAttr(XhtmlContext context, String attr, String key) {
		writeAttr(context, attr, key, null);
	}
	public static Collection<?> convertCollection(Object value){
		Collection<?> ite = null;
		if (value instanceof Collection) {
			ite = (Collection<?>) value;
		} else if (value instanceof Object[]) {
			ite = Arrays.asList(( Object[])value);
		} else if (value instanceof Map) {
			Map<?,?> temp=(Map<?, ?>) value;
			ite = temp.entrySet();
		} else {
			throw new XhtmlException("value is not Iterable");
		}
		return ite;
	}
}
